package numberporting.client;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.ws.soap.SOAPFaultException;
import numberporting.bean.Customer;
import numberporting.service.INotificationService;
import numberporting.bean.PortingRequest;
import numberporting.service.INumberPortingService;
import numberporting.service.InvalidCustomerException;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;

/**
 *
 * @author Thomas
 */
public class Client {

    private String host; 
    private org.apache.cxf.endpoint.Endpoint cxfEndpoint;
    
    public static void main(String[] args)
    {
        Client client = new Client();
        client.testNumberPortingService();
        client.testSmsService();
        client.testMailService();
        client.testCustomerService();
        
        System.exit(0);
    }
    
    
    public WSS4JOutInterceptor addWssInterceptors(org.apache.cxf.endpoint.Client client, boolean rightPassword) {
        cxfEndpoint = null;
        WSS4JOutInterceptor wssOut = null;
        cxfEndpoint = client.getEndpoint();
        Map<String,Object> outProps = new HashMap<String, Object>();
        outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
        outProps.put(WSHandlerConstants.USER, "joe");   
        outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
        if (rightPassword) {
            outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordCallback.class.getName());
        } else {
            outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientWrongPasswordCallback.class.getName());
        }
        wssOut = new WSS4JOutInterceptor(outProps);
        cxfEndpoint.getOutInterceptors().add(wssOut);
        return wssOut;
        
    }
    
    public void testMailService() {
        System.out.println("testing MailService");
        System.out.println("-----------------------------------");
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
       // factory.getInInterceptors().add(new LoggingInInterceptor());
       // factory.getOutInterceptors().add(new LoggingOutInterceptor());
        factory.setServiceClass(INotificationService.class);
        factory.setAddress("http://localhost:8089/mailservice");
        INotificationService service = (INotificationService)factory.create();
        org.apache.cxf.endpoint.Client client = factory.getClientFactoryBean().getClient();
        
        addWssInterceptors(client, true);
       
        Customer customer = new Customer("1","Christian");
        
        boolean ok;
        try {
            ok = service.notify_customer(customer, "hello customer 234");
            System.out.println("Vom Server an Client: "+ok);
        } catch (SOAPFaultException ex) {
            System.out.println("oje eine exception!"+ex.getMessage());
        } catch (Exception ex) {
            System.out.println("exception thrown: "+ex.getMessage());
        }
        
    }
    
    public void testSmsService() {
        System.out.println("testing SmsService");
        System.out.println("-----------------------------------");
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
       // factory.getInInterceptors().add(new LoggingInInterceptor());
       // factory.getOutInterceptors().add(new LoggingOutInterceptor());
        factory.setServiceClass(INotificationService.class);
        factory.setAddress("http://localhost:8088/smsservice");
        INotificationService service = (INotificationService)factory.create();
        org.apache.cxf.endpoint.Client client = factory.getClientFactoryBean().getClient();
        
        Customer customer = new Customer("2","Thomas");
        boolean ok;
        
        System.out.println("Trying to invoke SMS Service w/o Security headers: ");
        
        try {
            ok = service.notify_customer(customer, "hello customer 2");
            System.out.println("Vom Server an Client: "+ok);
        } catch (SOAPFaultException ex) {
            System.out.println("SoapFaultException: "+ex.getMessage());
        } catch (Exception ex) {
            System.out.println("exception thrown: "+ex.getClass()+" | "+ex.getMessage());
        }
        
        System.out.println("Trying to invoke SMS Service with wrong Password: ");

        WSS4JOutInterceptor wssOut = addWssInterceptors(client, false);
        
        try {
            ok = service.notify_customer(customer, "hello customer 2");
            System.out.println("Vom Server an Client: "+ok);
        } catch (SOAPFaultException ex) {
            System.out.println("SoapFaultException: "+ex.getMessage());
        } catch (Exception ex) {
            System.out.println("exception thrown: "+ex.getClass()+" | "+ex.getMessage());
        }
        
        factory.getClientFactoryBean().getClient().getEndpoint().getOutInterceptors().remove(wssOut);
        addWssInterceptors(client, true);
  
        System.out.println("Trying to invoke SMS Service with correct Password: ");

        try {
            ok = service.notify_customer(customer, "hello customer 2");
            System.out.println("Vom Server an Client: "+ok);
        } catch (SOAPFaultException ex) {
            System.out.println("SoapFaultException: "+ex.getMessage());
        } catch (Exception ex) {
            System.out.println("exception thrown: "+ex.getClass()+" | "+ex.getMessage());
        }
        
        System.out.println("Trying to invoke SMS Service with very long Message: ");
        try {
            ok = service.notify_customer(customer, "hello customer 2hello customer 2hello customer 2hello customer 2hello customer 2hello customer 2hello customer 2hello customer 2hello customer 2");
            System.out.println("Vom Server an Client: "+ok);
        } catch (SOAPFaultException ex) {
            System.out.println("SoapFaultException: "+ex.getMessage());
        } catch (Exception ex) {
            System.out.println("exception thrown: "+ex.getClass()+" | "+ex.getMessage());
        }
        
        
    }
    public void testCustomerService(){
        
        System.out.println("testing CustomerService (XML)");
        System.out.println("-----------------------------------");
        CustomerManagementClient client = new CustomerManagementClient("http://localhost:8084/customers",false);
        this.testCustomerService(client);
        System.out.println("");
        System.out.println("testing CustomerService (JSON)");
        System.out.println("-----------------------------------");
        client = new CustomerManagementClient("http://localhost:8084/customers",true);
        this.testCustomerService(client);
    }
    public void testCustomerService(CustomerManagementClient client){
        String customerId = "1";
        System.out.println("get customer with id "+customerId);
        Customer c = null;
        try{
            c = client.getCustomer(customerId);
            if(c != null){
                System.out.println(c.toString());
            }
        }catch(Exception e){
            System.out.println(e.getMessage());
        }

        try{
            System.out.println("update customer with id "+customerId);
            c.setName("mr. new name");
            client.updateCustomer(c);

            c = client.getCustomer(customerId);
            if(c != null){
                System.out.println(c.toString());
            }
        }catch(Exception e){
            System.out.println(e.getMessage());
        }

        try{
            System.out.println("create customer with id 34563456");
            c = new Customer("34563456", "Mr New Guy");
            client.addCustomer(c);
            c = client.getCustomer("34563456");
            if(c != null){
                System.out.println(c.toString());
            }
        }catch(Exception e){
            System.out.println(e.getMessage());
        }

        try{
            System.out.println("retrieving non existent customer with id 34444");
            c = client.getCustomer("34444");
            if(c != null){
                System.out.println(c.toString());
            }
        }catch(Exception e){
            System.out.println(e.getMessage());
        }

        try{
            System.out.println("\ndeleting customer 34563456");
            client.deleteCustomer("34563456");
            c = client.getCustomer("34563456");
            if(c != null){
                System.out.println(c.toString());
            }
        }catch(Exception e){
            System.out.println(e.getMessage());
        }

    }
    public void testNumberPortingService()
    {
        System.out.println("testing NumberPortingService");
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(INumberPortingService.class);
        factory.setAddress("http://localhost:8083/numberportingservice");
        INumberPortingService service = (INumberPortingService)factory.create();
        org.apache.cxf.endpoint.Client client = factory.getClientFactoryBean().getClient();
        
        addWssInterceptors(client, true);
        
       Calendar cal = Calendar.getInstance();
        
        Customer customer = new Customer("1", "Christian");
        PortingRequest p = new PortingRequest();
        p.setCustomer(customer);
        p.setNew_provider(10);

        Customer c2 = new Customer("2", "Thomas");
        PortingRequest p2 = new PortingRequest();
        p2.setCustomer(c2);
        p2.setNew_provider(11);
        
        cal.set(2008, 11, 03, 22, 14, 00);
    	Date d1 = new Date();
        d1 = cal.getTime();
        p.setPorting_date(d1);
        
        cal.set(2008, 11, 03, 22, 12, 00);
        
        Date d2 = new Date();
        d2 = cal.getTime();
        p2.setPorting_date(d2);
        
        PortingRequest[] allRequest = {p,p2};
        
        Customer c3 = new Customer("4", "Illegal User");
        Customer c4 = new Customer("5", "Not Availbale");

        System.out.println("Check porting possible customer4 (Not Available)");
        try
        {
             System.out.println("Check porting possible customer4 (Not Available):" +service.check_porting_possible(c4, 10));
        }
        catch(Exception e)
        {
            System.out.println("Exception: "+e.getClass()+" | "+e.getMessage());
        }
        
        try
        {
            System.out.println("Check porting possible customer1: "+service.check_porting_possible(customer, 1));
            System.out.println("Check porting possible customer2: "+service.check_porting_possible(c2, 11));
            System.out.println("Check porting possible customer3 (Illegal User): "+service.check_porting_possible(c3, 10));
            
            System.out.println("Add porting Reqeusts to portingqueue");
            service.schedule_batch_porting(allRequest);
            
            boolean check1 = false;
            boolean check2 = false;
            while(!check1&&!check2)
            {
                check1 = service.check_porting_status(customer);
                check2 = service.check_porting_status(c2);
                
                System.out.println("Check porting Status 1: "+check1);
                System.out.println("Check porting Status 2: "+check2);
                
               Thread.sleep(30 * 1000);
            }
            System.out.println("PortingResult customer1: "+service.get_porting_result(customer).getCommment()+" New provider: "+service.get_porting_result(customer).getNew_provider());
            System.out.println("PortingResult customer2: "+service.get_porting_result(c2).getCommment()+" New provider: "+service.get_porting_result(c2).getNew_provider());
            

        }
        catch(Exception e)
        {
            System.err.println("Exception: " +e.getMessage());
        }
    }
    
}
